package com.wnxy.filter;

import com.wnxy.config.AuthPattern;
import com.wnxy.dto.ManagerDetail;
import com.wnxy.dto.RolePathDto;
import com.wnxy.service.impl.FailureHandler;
import com.wnxy.util.CommonsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.PathMatcher;
import java.util.List;
import java.util.stream.Collectors;

public class RoleAccessFilter extends OncePerRequestFilter {
    private AntPathMatcher apm=new AntPathMatcher();
    private FailureHandler fh;
    private RedisTemplate<String,Object> rt;
    private AuthPattern ap;
    public RoleAccessFilter(FailureHandler fh,RedisTemplate<String,Object> rt,AuthPattern ap) {
        this.fh = fh;
        this.rt=rt;
        this.ap=ap;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        Boolean flag= true;
        String uri=request.getRequestURI();
        if(uri.charAt(1)=='/') uri=uri.substring(1);
        System.out.println("认证权限"+uri);
        String[] permitPath = ap.getPatterns();
        for (String s : permitPath) {
            if (apm.match(s,uri)||s.equals(uri)){
                System.out.println("所有权限放行");
                flag=false;
                filterChain.doFilter(request,response);//程序放行权限
            }
        }
        if(flag){
            if(uri.equals("/manager/loadPower")){
                filterChain.doFilter(request,response);//加载权限到redis数据库放行
            }else {
                uri=uri+"/";
                uri=uri.substring(0, uri.indexOf("/", 2));
                System.out.println("认证权限"+uri);
                ManagerDetail managerDetail = (ManagerDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                Object o = rt.opsForValue().get("wnxy:theater:rolePath:" + managerDetail.getMangerRoleId());
                List<RolePathDto> rolePathDtos = CommonsUtil.castList(o, RolePathDto.class);
                System.out.println("权限认证开始,当前角色:"+managerDetail.getManagerName());
                List<String> urls = rolePathDtos.stream().map(rolePathDto -> rolePathDto.getPathUrl()).collect(Collectors.toList());
                if(!urls.contains(uri)) {
                    fh.onAuthenticationFailure(request,response,new InternalAuthenticationServiceException("没有权限访问"));
                }else {
                    filterChain.doFilter(request,response);
                }
            }
        }





    }
}
